<?php
/*
 * 转换URL--后缀
 *$arr = array(href)
 */
function fn_url($args) {
	global $website;

	// 重写url
	$rewrite = function (&$href) use (&$website) {
		if ($website['html']['rewrite']) {
			return preg_replace(
				array(
					'/\/act\.php\?act=article&id=(\d+)$/',
					'/\/act\.php\?act=list$/',
					// '/^\/data\/(.*?)\.(jpg|png|gif)$/'
				),
				array(
					$website['url']['root'] . '/article/\1/',
					'/list/',
					// $website['url']['root'].'/data/\1.\2/',
				),
				$href
			);
		}
		return $href;
	};

	$href = '/';
	if (is_string($args)) {
		$href = $rewrite($args);
	} elseif (is_array($args)) {
		extract($args);
		if (is_array($href)) {
			foreach ($href as $k => $v) {
				$href[$k] = $rewrite($v);
			}
		} else {
			$href = $rewrite($href);
		}
	}

	return $href;
	// return $href??'';
}

/*
 * 截取字符
 * $arr = array(str,len,sfx='...',start=0,coding='utf-8')
 */
function fn_substr($arr) {
	/*
		$str,$len,$sfx='...',$start=0,$coding='utf-8'
	*/
	extract($arr);
	$sfx = isset($sfx) ? $sfx : '...';
	$start = isset($start) ? $start : 0;
	$coding = isset($coding) ? $coding : 'utf-8';
	$lens = mb_strlen($str);
	if ($len < $lens) {
		return mb_substr($str, $start, $len, $coding) . $sfx;
	} else {
		return $str;
	}
}

// 设备信息
function fn_device() {
	if (stristr($_SERVER['HTTP_USER_AGENT'], 'iPad')) {
		return 'iPad';
	} elseif (stristr($_SERVER['HTTP_USER_AGENT'], 'Android')) {
		return 'Android';
	} elseif (stristr($_SERVER['HTTP_USER_AGENT'], 'Linux')) {
		return 'Linux';
	} elseif (stristr($_SERVER['HTTP_USER_AGENT'], 'iPhone')) {
		return 'iPhone';
	} else {
		return 'Pc';
	}
}

// 浏览器信息
function fn_browser() {
	if (preg_match('/MSIE\s(\d+)\..*/i', $_SERVER['HTTP_USER_AGENT'], $regs)) {
		return 'MSIE' . $regs[1];
	} elseif (preg_match('/FireFox\/(\d+)\..*/i', $_SERVER['HTTP_USER_AGENT'], $regs)) {
		return 'Firefox' . $regs[1];
	} elseif (preg_match('/Opera[\s|\/](\d+)\..*/i', $_SERVER['HTTP_USER_AGENT'], $regs)) {
		return 'Opera' . $regs[1];
	} elseif (preg_match('/Chrome\/(\d+)\..*/i', $_SERVER['HTTP_USER_AGENT'], $regs)) {
		return 'Chrome' . $regs[1];
	} elseif ((strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome') == false) && strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') !== false) {
		if (preg_match('/Version\/(\d+)\..* Safari/i', $_SERVER['HTTP_USER_AGENT'], $regs)) {
			return 'Safari' . $regs[1];
		} else {
			return 'Safari';
		}
	} elseif (preg_match('/Edge\/([\d\.]+)/i', $_SERVER['HTTP_USER_AGENT'], $regs)) {
		return 'Edge' . $regs[1];
	} else {
		return 'unknow';
	}
}

// 获取操作系统
function fn_os() {
	if (preg_match('/win/i', $_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], '95')) {
		return 'Windows 95';
	} elseif (preg_match('/win 9x/i', $_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], '4.90')) {
		return 'Windows ME';
	} elseif (preg_match('/win/i', $_SERVER['HTTP_USER_AGENT']) && preg_match('/98/', $_SERVER['HTTP_USER_AGENT'])) {
		return 'Windows 98';
	} elseif (preg_match('/win/i', $_SERVER['HTTP_USER_AGENT']) && preg_match('/nt 6.0/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'Windows Vista';
	} elseif (preg_match('/win/i', $_SERVER['HTTP_USER_AGENT']) && preg_match('/nt 6.1/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'Windows 7';
	} elseif (preg_match('/win/i', $_SERVER['HTTP_USER_AGENT']) && preg_match('/nt 6.2/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'Windows 8';
	} else if (preg_match('/win/i', $_SERVER['HTTP_USER_AGENT']) && preg_match('/nt 10.0/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'Windows 10'; #添加win10判断
	} elseif (preg_match('/win/i', $_SERVER['HTTP_USER_AGENT']) && preg_match('/nt 5.1/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'Windows XP';
	} elseif (preg_match('/win/i', $_SERVER['HTTP_USER_AGENT']) && preg_match('/nt 5/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'Windows 2000';
	} elseif (preg_match('/win/i', $_SERVER['HTTP_USER_AGENT']) && preg_match('/nt/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'Windows NT';
	} elseif (preg_match('/win/i', $_SERVER['HTTP_USER_AGENT']) && preg_match('/32/', $_SERVER['HTTP_USER_AGENT'])) {
		return 'Windows 32';
	} elseif (preg_match('/win/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'Windows';
	} elseif (preg_match('/linux/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'Linux';
	} elseif (preg_match('/unix/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'Unix';
	} elseif (preg_match('/sun/i', $_SERVER['HTTP_USER_AGENT']) && preg_match('/os/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'SunOS';
	} elseif (preg_match('/ibm/i', $_SERVER['HTTP_USER_AGENT']) && preg_match('/os/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'IBM OS/2';
	} elseif (preg_match('/Mac OS X/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'Mac';
	} elseif (preg_match('/PowerPC/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'PowerPC';
	} elseif (preg_match('/AIX/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'AIX';
	} elseif (preg_match('/HPUX/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'HPUX';
	} elseif (preg_match('/NetBSD/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'NetBSD';
	} elseif (preg_match('/BSD/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'BSD';
	} elseif (preg_match('/OSF1/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'OSF1';
	} elseif (preg_match('/IRIX/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'IRIX';
	} elseif (preg_match('/FreeBSD/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'FreeBSD';
	} elseif (preg_match('/teleport/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'teleport';
	} elseif (preg_match('/flashget/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'flashget';
	} elseif (preg_match('/webzip/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'webzip';
	} elseif (preg_match('/offline/i', $_SERVER['HTTP_USER_AGENT'])) {
		return 'offline';
	} else {
		return 'unknown';
	}
}

//获取访问者IP
function fn_ip() {
	$onlineip = '0.0.0.0';
	if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
		$onlineip = getenv('HTTP_CLIENT_IP');
	} elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
		$onlineip = getenv('HTTP_X_FORWARDED_FOR');
	} elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
		$onlineip = getenv('REMOTE_ADDR');
	} elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
		$onlineip = $_SERVER['REMOTE_ADDR'];
	}
	return $onlineip;
}

//返回ip转换成无负数long
function fn_ip_long($ip = '') {
	return bindec(decbin(ip2long($ip ? $ip : fn_ip())));
}

//解析session里的值，返回数组
function fn_session($str) {
	if (!isset($_SESSION[$str])) {return 0;}
	return json_decode($_SESSION[$str], 1);
}

// 判断用户的账户类型 返回 bool
function fn_authority(&$website, $authority, $name) {
	// $authority   用户权限值  100000....
	// $name        用户权名称  doctor name.....
	if (array_key_exists($name, $website['authority'])) {
		if ($website['authority'][$name] == $authority) {
			return true;
		}
	}
	return false;
}

//获取所有下级分类
function fn_next_type(&$website, $tid) {
	$tps = $website['class']['db']
		->table('type')
		->field()
		->where('upid=?', $tid)
		->select();
	foreach ($tps as $key => $tp) {
		if ($website['class']['db']->table('type')->where('upid=?', $tp['id'])->count()) {
			$tps[$key]['next'] = fn_next_type($website, $tp['id']);
		}
	}
	return $tps;
}

//功能：逐层创建文件夹
function fn_mkdir($path, $mode = 0775, $recursive = false) {
	global $website;
	$path = dirname($path);
	$path = str_replace($website['path']['data'], '', $path);
	$arr = explode('/', $path);
	array_shift($arr);
	$paths = $website['path']['data'];
	foreach ($arr as $v) {
		$paths .= '/' . $v;
		if (!is_dir($paths)) {
			try {
				if (!mkdir($paths, $mode, $recursive)) {
					return '创建文件夹：' . $paths . '失败!';
				}
			} catch (Exception $e) {
				return $e->getMessage();
			}
		}
	}
	return true;
}
// 功能:遍历文件夹 删除文件
// $path  完整地址
// $fname 文件名称
function fn_loop_del($path, $fname) {

	$loop = function ($path, $fname) use (&$loop) {
		$arr = scandir($path);
		foreach ($arr as $v) {
			if ($v == '.' || $v == '..') {
				continue;
			} elseif (is_dir($path . '/' . $v)) {
				$loop($path . '/' . $v, $fname);
			} elseif (is_file($path . '/' . $v) && $v == $fname) {
				unlink($path . '/' . $v);
			} else {
				continue;
			}
		}
	};
	$loop($path, $fname);
}

//格式化时间
function fn_format_time($args) {
// args(
	//   'time'=>''  LINUX时间
	//   'format'=>'Y-m-d'   格式化
	// )
	extract($args);

	return date($format, $time);

}

//获取当前星期一至星期日的日期
function fn_mon_to_sun() {
	//当前时间
	$now = explode('-', date('Y-m-d'));
	//当前凌晨时间 linux格式
	$time = mktime(0, 0, 0, $now[1], $now[2], $now[0]);
	//当前时间-(星期几-1)*一天的秒数=星期一时间
	$monday = $time - (date('N') - 1) * 86400;
	$month = array(date('Ymd', $monday));
	for ($i = 1; $i < 7; $i++) {
		array_push($month, date('Ymd', $monday + ($i * 86400)));
	}
	return $month;
}

//页面跳转
function fn_jump_url(&$website, $arrs) {
	$arr = array(
		'url' => $website['url']['root'],
		'alert' => '必须登录后才能使用此功能!',
		'second' => 3,
	);
	if (isset($arrs) && is_array($arrs)) {
		$arr = array_merge($arr, $arrs);
	}

	$website['class']['tpl']

		->assign('tit', '提示')
		->assign('alert', $arr)
		->display('alert.tpl');
	exit();
}

//直接跳转
function fn_jump_header($url) {
	header('Location:' . $url);
	exit();
}
// 地址后退
function fn_jump_header_back() {
	header('Cache-control: private');
	exit();
}

//获取省市区  直辖市没有下级
function fn_province_city(&$website) {
	$arr = $website['class']['db']
		->table('type')
		->field('id')
		->where('upid=' . $website['tid']['pivCit'])
		->select();
	$pc = array();
	foreach ($arr as $v) {
		//省 直辖市
		$arrs = $website['class']['db']
			->table('type')
			->field('id', 'tit', 'tp')
			->where('upid=' . $v['id'])
			->select();
		//如果是直辖市就下一个
		foreach ($arrs as $k => $vv) {
			$c = $website['class']['db']
				->table('type')
				->field('id', 'tit')
				->where('upid=' . $vv['id'])
				->select();
			$vv['next'] = $c;
			array_push($pc, $vv);
		}
	}
	return $pc;
}

// 与当前时间比较
// 分钟级别  具体大于的分钟
// 小时级别  具体大于的小时
// 天级别    ........天
// 月       ........月
// 年       ........年
function fn_contrast_time($time) {
	$contrast = $_SERVER['REQUEST_TIME'] - $time;
	$year = 6060243012;
	$month = 60602430;
	$day = 606024;
	$hour = 3600;
	$minute = 60;
	if ($contrast > $year) {
		return array('time' => floor($contrast / $year), 'val' => '年');
	} elseif ($contrast > $month) {
		return array('time' => floor($contrast / $month), 'val' => '月');
	} elseif ($contrast > $day) {
		return array('time' => floor($contrast / $day), 'val' => '天');
	} elseif ($contrast > $hour) {
		return array('time' => floor($contrast / $hour), 'val' => '小时');
	} elseif ($contrast > $minute) {
		return array('time' => floor($contrast / $minute), 'val' => '分钟');
	} else {
		return array('time' => $contrast, 'val' => '秒');
	}
}

// 获取毫秒数
function fn_millisecond() {
	list($t1, $t2) = explode(' ', microtime());
	return (float) sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
}

//根据 key 删除二维数组中的重复值
function fn_unique_multidim_array(&$array, $key) {
	$temp_array = array();
	$i = 0;
	$key_array = array();

	foreach ($array as $val) {
		if (!in_array($val[$key], $key_array)) {
			$key_array[$i] = $val[$key];
			$temp_array[$i] = $val;
		}
		$i++;
	}
	return $temp_array;
}

// 递归合并二维数组
function fn_array_merge_recursive_distinct(array &$array1, array &$array2) {
	$merged = $array1;
	foreach ($array2 as $key => &$value) {
		if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
			$merged[$key] = fn_array_merge_recursive_distinct($merged[$key], $value);
		} else {
			$merged[$key] = $value;
		}
	}
	return $merged;
}
// 二维数组根据某元素排序
// SORT_ASC - 默认，按升序排列。(A-Z)
// SORT_DESC - 按降序排列。(Z-A)
// 随后可以指定排序的类型：
// SORT_REGULAR - 默认。将每一项按常规顺序排列。
// SORT_NUMERIC - 将每一项按数字顺序排列。
// SORT_STRING - 将每一项按字母顺序排列
function fn_array_sort($arrays, $sort_key, $sort_order = SORT_ASC, $sort_type = SORT_NUMERIC) {
	if (is_array($arrays)) {
		foreach ($arrays as $array) {
			if (is_array($array)) {
				$key_arrays[] = $array[$sort_key];
			} else {
				return false;
			}
		}
	} else {
		return false;
	}
	array_multisort($key_arrays, $sort_order, $sort_type, $arrays);
	return $arrays;
}

// 返回当前页面分页最大最小值
function fn_page(&$paging, $num) {
	if ($paging['maxPage'] < $num || $paging['maxPage'] - $num <= 1) {
		return array(
			'min' => 1,
			'max' => $paging['maxPage'],
		);
	} else {

		$max = ceil($paging['nowPage'] / $num) * $num + 1;

		$max = $max > $paging['maxPage'] ? $paging['maxPage'] : $max;

		$min = $max - $num;
		return array('min' => $min, 'max' => $max);
	}
}
// 根据数字解析返回账户的权限名称
function fn_user_authority_resolve(&$authority) {
	if ($authority[0] != '1') {return 0;}
	$back = [];
	// 管理员
	if ($authority[1] == '1') {
		$back[] = 'edit';
	} elseif ($authority[1] == '2') {
		$back[] = 'admin';
	}
	return $back;
}
// 根据数组 返回权限数字
function fn_user_authority_num(&$arr) {
	// 默认权限
	$authority = 100000;
	if (in_array('admin', $arr) && in_array('edit', $arr)) {
		unset($arr[array_search('edit', $arr)]);
	}
	if (in_array('edit', $arr)) {
		$authority += 10000;
	} elseif (in_array('admin', $arr)) {
		$authority += 20000;
	}

	return $authority;
}

// 返回一天之间的事件数
function fn_between_time($time = 0) {
	$time = (isset($time) && $time) ? $time : $_SERVER['REQUEST_TIME'];
	$year = date('Y', $time);
	$month = date('m', $time);
	$day = date('d', $time);
	$first = mktime(0, 0, 0, $month, $day, $year);
	$last = mktime(23, 59, 59, $month, $day, $year);
	return array('first' => $first, 'last' => $last);
}

// 提交一条数据到百度
function fn_baidu_push($domain, $url) {
	$api = 'http://data.zz.baidu.com/urls?site=' . $domain . '&token=RbbznE6g4jon1k3D';
	$ch = curl_init();
	$options = array(
		CURLOPT_URL => $api,
		CURLOPT_POST => true,
		CURLOPT_RETURNTRANSFER => true,
		CURLOPT_POSTFIELDS => implode("\n", $url),
		CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
	);
	curl_setopt_array($ch, $options);
	return curl_exec($ch);
}

// 返回链接内容
function fn_show_links(&$website, $tid, $num = 1, $desc = 'desc') {
	if ($num !== 1) {
		return $website['class']['db']
			->table('links')
			->field('tit', 'href', 'image')
			->where('tid=?', $tid)
			->limit($num)
			->order('id ' . $desc)
			->select();
	} else {
		return $website['class']['db']
			->table('links')
			->field('tit', 'href', 'image')
			->where('tid=?', $tid)
			->order('id ' . $desc)
			->one();
	}
}

// 缩略图
function fn_image_Thumbnail($src, $width = null, $height = null, $filename = null) {
	if (!isset($width) && !isset($height)) {
		return false;
	}

	if (isset($width) && $width <= 0) {
		return false;
	}

	if (isset($height) && $height <= 0) {
		return false;
	}

	$size = getimagesize($src);
	if (!$size) {
		return false;
	}

	list($src_w, $src_h, $src_type) = $size;
	$src_mime = $size['mime'];
	switch ($src_type) {
	case 1:
		$img_type = 'gif';
		break;
	case 2:
		$img_type = 'jpeg';
		break;
	case 3:
		$img_type = 'png';
		break;
	case 15:
		$img_type = 'wbmp';
		break;
	default:
		return false;
	}

	if (!isset($width)) {
		$width = $src_w * ($height / $src_h);
	}

	if (!isset($height)) {
		$height = $src_h * ($width / $src_w);
	}

	$imagecreatefunc = 'imagecreatefrom' . $img_type;
	$src_img = $imagecreatefunc($src);
	$dest_img = imagecreatetruecolor($width, $height);
	imagecopyresampled($dest_img, $src_img, 0, 0, 0, 0, $width, $height, $src_w, $src_h);

	$imagefunc = 'image' . $img_type;
	if ($filename) {
		fn_mkdir($filename);
		$imagefunc($dest_img, $filename);
	} else {
		header('Content-Type: ' . $src_mime);
		$imagefunc($dest_img);
	}
	imagedestroy($src_img);
	imagedestroy($dest_img);
	return true;
}

// 微信数据
function fn_wx_appoved(&$website) {
	$fn_wx_data = function () use (&$website) {
		$cont = file_get_contents('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential' .
			'&appid=' . $website['wx']['appid'] .
			'&secret=' . $website['wx']['secret']
		);
		$wxJson = json_decode($cont, 1);
		$jsCont = file_get_contents('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' . $wxJson['access_token'] . '&type=jsapi');
		$jsJson = json_decode($jsCont, 1);

		return array(
			'time' => $_SERVER['REQUEST_TIME'],
			'appid' => $website['wx']['appid'],
			'secret' => $website['wx']['secret'],
			'expires_in' => $wxJson['expires_in'] ?? 7200,
			'access_token' => $wxJson['access_token'],
			'jsapi_ticket' => $jsJson['ticket'],
		);
	};

	$json = [];
	$path = $website['path']['temp'] . '/wx.temp';
	if (is_file($path)) {
		$data = json_decode(file_get_contents($path), 1);
		if ($data['time'] + $website['wx']['expires_in'] - $_SERVER['REQUEST_TIME'] > 0) {
			$json['data'] = $data;
		} else {
			$json['data'] = $fn_wx_data();
			file_put_contents($path, json_encode($json['data']));
		}
	} else {
		$json['data'] = $fn_wx_data();
		file_put_contents($path, json_encode($json['data']));
	}

	$arr = range(1, 50);
	$str = array_rand($arr, 10);
	$nonceStr = implode('', $str);
	$key = 'jsapi_ticket=' . $json['data']['jsapi_ticket'] . '&' .
		'noncestr=' . $nonceStr . '&' .
		'timestamp=' . $_SERVER['REQUEST_TIME'] . '&' .
		'url=' . $_SERVER['HTTP_REFERER'];
	$signature = sha1($key);

	$json['data']['time'] = $_SERVER['REQUEST_TIME'];
	$json['data']['nonceStr'] = $nonceStr;
	$json['data']['signature'] = $signature;
	// $json['data']['key']        = $key;
	return $json['data'];
}

function fn_post($str, $def = false) {
	return $_POST[$str] ?? $def;
}
function fn_get($str, $def = false) {
	return $_GET[$str] ?? $def;
}

// params[1,2,3]:{1}验证码为：{2}，请于{3}分钟内输入完成验证。如非本人操作请忽略。
// 指定模板发送短信
function fn_sms_tpl(&$website, $phone, $tp, $params) {
	// $str = "{1}验证码为：{2}，请于{3}分钟内输入完成验证。如非本人操作请忽略。";
	// $msg = preg_replace(['/\{1\}/','/\{2\}/','/\{3\}/'],$params,$str);
	try {
		$result = $website['class']['sms']
			->sendWithParam(
				"86",
				$phone,
				$website['tx']['sms']['templid'],
				$params,
				'', '', ''
			);
		$website['class']['db']
			->table('sms')
			->field('createtime', 'phone', 'ip', 'send', 'tp', 'msg')
			->value($_SERVER['REQUEST_TIME'], $phone, fn_ip_long(), 1, $tp, $params[1])
			->insert();
		return true;
	} catch (Exception $e) {
		return false;
	}
}

// 绝对路径转相对路径
function abs2rel(string $base, string $path) {
	if (is_dir($base)) {
		$base = rtrim($base, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . ".";
	}

	$a = explode(DIRECTORY_SEPARATOR, $base);
	$b = explode(DIRECTORY_SEPARATOR, $path);

	$d = []; // $path push
	$i = count($a) - 1;

	$sliceEquals = function ($a, $b, $j) {
		if ($j >= count($a) || $j >= count($b)) {
			throw new Exception('$j out of range');
		}
		for ($i = $j; $i >= 0; $i--) {
			if (strcmp($b[$i], $a[$i]) !== 0) {
				return false;
			}
		}
		return true;
	};
	// 找到a,b数组元素相同的下标
	while (array_pop($a)) {
		$i = count($a) - 1;
		if (isset($b[$i])) {
			if ($sliceEquals($a, $b, $i)) {
				break;
			}
		}
		array_push($d, "..");
	}
	// 从首个不同元素开始
	for ($i += 1; $i < count($b); $i++) {
		array_push($d, $b[$i]);
	}
	return "." . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $d);
}

// 返回配置信息
function fn_configura(&$website, $k) {
	$configura = $website['class']['db']
		->table('configura')
		->field('v')
		->where('k=?', $k)
		->one();
	return json_decode($configura['v'], 1);
}

// 图片地址转换  本地地址或网络地址替换
function fn_image(&$website, $url) {
	if (!preg_match('/^http(s?)\:\/\//', $url)) {
		return $website['url']['image'] . $url;
	} else {
		return $url;
	}
}

// 发送注册验证码
function fn_sms_code_register($tp, $phone, $code) {

}

// 检测商品价格和上传颜色规格价格是否一致
/**
 * [fn_check_prarms_prices 检测商品价格和上传颜色规格价格是否一致]
 * @Author   ddyake
 * @DateTime 2020-05-14
 * @param    [array]     $param [上传价格]
 * @param    [array]     $params [数据库内的价格]
 * @return   [float]    $price  [返回价格]
 */
function fn_check_params_prices($param, $params) {

	foreach ($params as $v) {
		$temp = array_splice($v, 0, count($v) - 3);
		if (implode('', $temp) === implode('', $param)) {
			return $v;
		}
	}
	return 0;
}

/**
 * [fn_prices_for_order 根据订单返回总价以及可用的优惠券]
 * @Author   ddyake
 * @DateTime 2020-05-16
 * @param    [Object]    &$website [description]
 * @param    [[Array]]     $arrParams   [订单参数]---[[pid:9,price:1,num:1,param:["颜色","大小"]],...]
 * @param    [Int]       $uid      [所属用户ID]
 * @return   [Array]     $json     [数组对象]
 */
function fn_prices_for_order(&$website, $arrParams, $uid) {

	$json = array('status' => 'error', 'msg' => '', 'data' => []);

	// 测试数据
	// $arrParams = '[{"pid":11,"param":["蓝色"],"price":227.24,"num":1}]';
	// $uid = 8;

	if (!$arrParams || !count($arrParams)) {
		$json['msg'] = '参数异常';
		$json['code'] = 1002;
		return $json;
	}

	// 拥有的未用优惠
	$coupon_user = $website['class']['db']
		->field('cid')
		->table('coupon_user')
		->where('uid=? and used=0 and endtime>?', $uid, $_SERVER['REQUEST_TIME'])
		->select();

	// 所有商品ID
	$pids = [];
	// 可用优惠券信息及使用后的价格
	$coupon = [];
	// 总价格
	$total = 0;
	// 商铺信息
	$shop = [];
	// 商铺邮费数据
	$postage = [];

	foreach ($arrParams as $k => $v) {
		$pids[] = $v['pid'];
		$param = $v['param'];
		// 商品数据
		$product = $website['class']['db']
			->table('product')
			->where('id =?', $v['pid'])
			->one();
		$arrParams[$k]['product'] = $product;
		// 购物车id
		$arrParams[$k]['cid'] = $v['cid'];
		// 商铺信息
		if (!count($shop)) {
			$shop = $website['class']['db']
				->table('shops')
				->where('id=?', $product['uid'])
				->one();
		}
		$params = $website['class']['db']
			->table('product_params')
			->field('prices')
			->where('id =?', $v['pid'])
			->one();

		$arr = json_decode($params['prices'], 1);

		$bool = 0;
		if ($param && count($param)) {
			$prices = fn_check_params_prices($param, $arr);
			$arrParams[$k]['prices'] = $prices;
			if (!$prices) {
				$bool = 0;
			} elseif ($v['price'] == bcdiv($prices[count($prices) - 2] * $product['discount'], 10000, 2)) {
				$bool = 1;
				$total = bcadd($total, bcmul($v['price'], $v['num'], 2), 2);

			}
		} elseif ($v['price'] == bcdiv($product['price'] * $product['discount'], 10000, 2)) {
			$bool = 1;
			$total = bcadd($total, bcmul($v['price'], $v['num'], 2), 2);
		}
		if (!$bool) {
			$json['msg'] = '数据已改变,请重新发送!';
			$json['data'] = 'change';
			return $json;
		}

	}

	// 我的邮费
	if (!count($postage)) {
		$postage = $website['class']['db']
			->field('postage')
			->table('shops_postage')
			->where('id=?', $shop['id'])
			->one();
	}

	// 检测商品是否可用优惠券
	foreach ($coupon_user as $v) {
		$cid = $v['cid'];
		$arrCoupon = $website['class']['db']
			->table('coupon')
			->where('id=?', $v['cid'])
			->one();

		// 使用范围 scope  0全场 1单品 2单类 3全店
		switch ($arrCoupon['scope']) {
		case 0: //全场可使用
			if (preg_match("/^-\d+$/", $arrCoupon['conditions'])) {
				//直减
				$coupon[] = array(
					'cid' => $cid,
					'coupon' => $arrCoupon,
					'total' => bcsub($total, (float) str_replace('-', '', $arrCoupon['conditions']), 2),
				);
			} elseif (preg_match("/^\d+-\d+$/", $arrCoupon['conditions'])) {
				//满减
				$arrMan = explode('-', $arrCoupon['conditions']);
				$coupon[] = array(
					'cid' => $cid,
					'coupon' => $arrCoupon,
					'total' => $total > $arrMan[0] ? bcsub($total, $arrMan[1], 2) : $total,
				);
			} elseif (preg_match("/^\d+/", $arrCoupon['conditions'])) {
				//折扣 95 96折
				$p = $arrParams[0]['price'];
				$total = bcsub($total, $p, 2);
				$coupon[] = array(
					'cid' => $cid,
					'coupon' => $arrCoupon,
					'total' => bcadd($total + bcdiv($p * $arrCoupon['conditions'], 100, 2)),
				);
			}
			break;
		case 1: //只能单个商品使用
			if (in_array($arrCoupon['pid'], $pids)) {
				$pPrice = 0;
				foreach ($arrParams as $v) {
					echo "价格", $v['price'], "<br />";
					if ($v['product']['id'] == $arrCoupon['pid']) {
						$pPrice = $v['price'];
						break;
					}
				}
				if (preg_match("/^-\d+$/", $arrCoupon['conditions'])) {
					//直减
					$coupon[] = array(
						'cid' => $cid,
						'coupon' => $arrCoupon,
						'total' => bcsub($total, (float) str_replace('-', '', $arrCoupon['conditions']), 2),
					);
				} elseif (preg_match("/^\d+-\d+$/", $arrCoupon['conditions'])) {
					//满减
					$arrMan = explode('-', $arrCoupon['conditions']);
					$coupon[] = array(
						'cid' => $cid,
						'coupon' => $arrCoupon,
						'total' => $pPrice > $arrMan[0] ? bcsub($total, $arrMan[1], 2) : $total,
					);
				} elseif (preg_match("/^\d+/", $arrCoupon['conditions'])) {
					//折扣 95 96折
					$total = bcsub($total, $pPrice, 2);
					$coupon[] = array(
						'cid' => $cid,
						'coupon' => $arrCoupon,
						'total' => bcadd($total, bcdiv($pPrice * $arrCoupon['conditions'], 100, 2), 2),
					);
				}
			}
			break;
		case 2: //单个种类商品使用
			foreach ($arrParams as $v) {
				if ($v['product']['tid'] == $arrCoupon['tid']) {
					if (preg_match("/^-\d+$/", $arrCoupon['conditions'])) {
						//直减
						$coupon[] = array(
							'cid' => $cid,
							'coupon' => $arrCoupon,
							'total' => bcsub($total, (float) str_replace('-', '', $arrCoupon['conditions']), 2),
						);
					} elseif (preg_match("/^\d+-\d+$/", $arrCoupon['conditions'])) {
						//满减
						$arrMan = explode('-', $arrCoupon['conditions']);
						$coupon[] = array(
							'cid' => $cid,
							'coupon' => $arrCoupon,
							'total' => $v['price'] > $arrMan[0] ? bcsub($total, $arrMan[1], 2) : $total,
						);
					} elseif (preg_match("/^\d+/", $arrCoupon['conditions'])) {
						//折扣 95 96折
						$total = bcsub($total, $v['price'], 2);
						$coupon[] = array(
							'cid' => $cid,
							'coupon' => $arrCoupon,
							'total' => bcadd($total, bcdiv($v['price'] * $arrCoupon['conditions'], 100, 2), 2),
						);
					}
					break;
				}
			}
			break;
		case 3: //只能在单个店内使用
			if ($arrCoupon['sid'] == $shop['id']) {
				if (preg_match("/^-\d+$/", $arrCoupon['conditions'])) {
					//直减
					$coupon[] = array(
						'cid' => $cid,
						'coupon' => $arrCoupon,
						'total' => bcsub($total, (float) str_replace('-', '', $arrCoupon['conditions']), 2),
					);
				} elseif (preg_match("/^\d+-\d+$/", $arrCoupon['conditions'])) {
					//满减
					$arrMan = explode('-', $arrCoupon['conditions']);
					$coupon[] = array(
						'cid' => $cid,
						'coupon' => $arrCoupon,
						'total' => $total > $arrMan[0] ? bcsub($total, $arrMan[1], 2) : $total,
					);
				} elseif (preg_match("/^\d+/", $arrCoupon['conditions'])) {
					//折扣 95 96折
					$p = $arrParams[0]['price'];
					$total = bcsub($total, $p, 2);
					$coupon[] = array(
						'cid' => $cid,
						'coupon' => $arrCoupon,
						'total' => bcadd($total + bcdiv($p * $arrCoupon['conditions'], 100, 2)),
					);
				}
			}
			break;
		default:
		}
	}

	$json['status'] = 'ok';
	$json['data'] = array(
		'total' => $total,
		'params' => $arrParams,
		'shop' => $shop,
		'postage' => $postage['postage'] ?? [],
		'coupon' => $coupon, //可用优惠券列表-包含使用后的总价
	);
	return $json;
}

/**
 * [fn_price_cheked 检测已有参数价格是否发生改变]
 * @Author   ddyake
 * @DateTime 2020-06-02
 * @param    [Object]    &$website [各类对象及配置集合]
 * @param    [Array]     $param    [订单参数]   ：[pid:9,price:1,num:1,param:["颜色","大小"]]
 * @return   [Bool]      $bool     [false未改变，true已改变]
 */
function fn_price_cheked(&$website, $param) {
	$params = $website['class']['db']
		->table('product_params')
		->field('prices')
		->where('id=?', $param['pid'])
		->one();
	$prices = json_decode($params['prices'], 1);

	$product = $website['class']['db']
		->table('product')
		->where('id=?', $param['pid'])
		->one();

	// 无多个规格颜色价格
	if (!count($prices)) {
		$price = bcdiv($product['price'] * $product['discount'], 100);
		if ($price == $param['price']) {
			return false;
		} else {
			return true;
		}
	} elseif (count($prices) && !count($param['param'])) {
//有多个规格颜色价格 但参数无规格颜色价格
		return true;
	} else {
		foreach ($prices as $v) {
			// [库存，价格，图片]
			$pe = array_slice($v, -3, 3);
			// [颜色,大小,...]
			$pm = array_slice($v, 0, count($v) - 3);

			if (bcdiv($pe[1] * $product['discount'], 100) == $param['price'] && implode($pm) === implode($param['param'])) {
				return false;
			}
		}
		return true;
	}
}

// 微信签名
function fn_wxGetSign($params, $key) {

	ksort($params); //将参数数组按照参数名ASCII码从小到大排序
	foreach ($params as $k => $v) {
		if ($k != "sign" && $v != "" && !is_array($v)) { //剔除参数值为空的参数
			$newArr[] = $k . '=' . $v; // 整合新的参数数组
		}
	}

	$stringA = implode("&", $newArr); //使用 & 符号连接参数
	$stringSignTemp = trim($stringA . "&key=" . $key); //拼接key
	// key是在商户平台API安全里自己设置的
	$stringSignTemp = hash_hmac("sha256", $stringSignTemp, $key);
	// $stringSignTemp = MD5($stringSignTemp); //将字符串进行MD5加密
	$sign = strtoupper($stringSignTemp); //将所有字符转换为大写
	return $sign;
}